﻿using System;

public class ByteArray  {
	//默认大小
	const int DEFAULT_SIZE = 1024;
	//初始大小
	int initSize = 0;
	//缓冲区
	public byte[] bytes;
	//读写位置 读的位置是这条消息的第一个元素在缓冲区的下标
    //通常把度过的消息清除掉 那么读的位置一般都是缓冲区的第一个元素开始 也就是下标为0的位置
	public int readIdx = 0;
    //写的位置是一条消息的长度（包括长度信息的两个字节）
	public int writeIdx = 0;
    //容量 是指缓冲区的长度 也就是bytes.Length;  将程序改掉了 后面不在用了
    private int capacity = 0;
	//剩余空间
	public int remain { get { return bytes.Length - writeIdx; }}
	//一条数据长度
	public int length { get { return writeIdx-readIdx; }}

	//构造函数
	public ByteArray(int size = DEFAULT_SIZE){
		bytes = new byte[size];
		capacity = bytes.Length;
        initSize = bytes.Length;
        readIdx = 0;
		writeIdx = 0;
	}

	//构造函数
	public ByteArray(byte[] defaultBytes){
		bytes = defaultBytes;
		capacity = bytes.Length;
        initSize = bytes.Length;
        readIdx = 0;
		writeIdx = bytes.Length;
	}

	//重设尺寸
	public void ReSize(int size){
		if(size < length) return;
		if(size < initSize) return;
		int n = 1;
		while(n<=size) n = n << 1;//这里和原书不同
        byte[] newBytes = new byte[n];
        capacity = bytes.Length;
        Array.Copy(bytes, readIdx, newBytes, 0, writeIdx-readIdx);
		bytes = newBytes;
		writeIdx = length;
		readIdx = 0;
	}

	//写入数据
	public int Write(byte[] bs, int offset, int count){
		if(remain < count){
			ReSize(length + count);
		}
		Array.Copy(bs, offset, bytes, writeIdx, count);
		writeIdx+=count;
		return count;
	}

	//读取数据
	public int Read(byte[] bs, int offset, int count){
		count = Math.Min(count, length);
		Array.Copy(bytes, 0, bs, offset, count);
		readIdx+=count;
		CheckAndMoveBytes();
		return count;
	}

	//检查并移动数据
	public void CheckAndMoveBytes(){
		if(length < 8){
			MoveBytes();
		}
	}

	//移动数据
	public void MoveBytes(){
		Array.Copy(bytes, readIdx, bytes, 0, length);
		writeIdx = length;
		readIdx = 0;
	} 

	//读取Int16
	public Int16 ReadInt16(){
		if(length < 2) return 0;
		Int16 ret = BitConverter.ToInt16(bytes, readIdx);
		readIdx += 2;
		CheckAndMoveBytes();
		return ret;
	}
    public UInt16 ReadUInt16()
    {
        return (UInt16)((bytes[readIdx + 1] << 8) | bytes[readIdx]);
    }

	//读取Int32
	public Int32 ReadInt32(){
		if(length < 4) return 0;
		Int32 ret = BitConverter.ToInt32(bytes, readIdx);
		readIdx += 4;
		CheckAndMoveBytes();
		return ret;
	}



	//打印缓冲区
	public override string ToString(){
		return BitConverter.ToString(bytes, readIdx, length);
	}

	//打印调试信息
	public string Debug(){
		return string.Format("readIdx({0}) writeIdx({1}) bytes({2})",
			readIdx,
			writeIdx,
			BitConverter.ToString(bytes, 0, capacity)
		);
	}
}
